import {DataUri, Graph} from '@antv/x6';
import ConfigGraph from "./config/ConfigGraph";
import config from "./config/ConfigGraph";

let graph = {}
let elContainer = undefined
let onNodeConfigEventListen = () => {}
function init(elContainerT) {
    elContainer = elContainerT
    let options = ConfigGraph.initOptions(elContainer)
    graph = new Graph(options);
    initListen()
    initChangePort()
    initNodeClick()
    initKey()
    // 设置居中
    graph.centerContent()
    return graph
}

const initOnNodeConfigEventListen = (onNodeConfigEventListenT) => {
    onNodeConfigEventListen = onNodeConfigEventListenT
}

function initNodeClick() {
    //监听节点和边的单击
    graph.on('cell:click', ({ e, x, y, cell, view }) => {

    })
    graph.on('node:contextmenu', ({ e, x, y, cell, view }) => {
        if (!cell.store.data.data) {
            cell.store.data.data = {}
        }
        cell.store.data.data.id = cell.id
        onNodeConfigEventListen(cell.store.data.data)
    })
    // 监听双击事件
    graph.on('node:dblclick', ({ cell, view, e }) => {
        const isNode = cell.isNode()
        const name = node ? 'node-editor' : 'edge-editor'
        cell.removeTool(name)
        cell.addTools({
            name,
            args: {
                event: e,
                attrs: {
                    backgroundColor: isNode ? '#EFF4FF' : '#FFF',
                },
            },
        })
    })
}

function initKey() {
    graph.bindKey(['meta+c', 'ctrl+c'], () => {
        const cells = graph.getSelectedCells()
        if (cells.length) {
            graph.copy(cells)
        }
        return false
    })
    graph.bindKey(['meta+x', 'ctrl+x'], () => {
        const cells = graph.getSelectedCells()
        if (cells.length) {
            graph.cut(cells)
        }
        return false
    })
    graph.bindKey(['meta+v', 'ctrl+v'], () => {
        if (!graph.isClipboardEmpty()) {
            const cells = graph.paste({ offset: 32 })
            graph.cleanSelection()
            graph.select(cells)
        }
        return false
    })
    graph.bindKey(['meta+z', 'ctrl+z'], () => {
        if (graph.history.canUndo()) {
            graph.history.undo()
        }
        return false
    })
    graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => {
        if (graph.history.canRedo()) {
            graph.history.redo()
        }
        return false
    })

    graph.bindKey(['meta+a', 'ctrl+a'], (event) => {
        const nodes = graph.getNodes()
        if (nodes) {
            graph.select(nodes)
        }
    })

    graph.bindKey(['backspace', 'delete'], () => {
        const cells = graph.getSelectedCells()
        if (cells.length) {
            graph.removeCells(cells)
        }
    })

    graph.bindKey(['ctrl+1', 'meta+1'], () => {
        const zoom = graph.zoom()
        if (zoom < 1.5) {
            graph.zoom(0.1)
        }
    })
    graph.bindKey(['ctrl+2', 'meta+2'], () => {
        const zoom = graph.zoom()
        if (zoom > 0.5) {
            graph.zoom(-0.1)
        }
    })
}

function initListen() {
    // graph.on('selection:changed', ({
    //                                    added,     // 新增被选中的节点/边
    //                                    removed,   // 被取消选中的节点/边
    //                                    selected,  // 被选中的节点/边
    //                                    options,
    //                                }) => {
    //     selected.forEach((cell) => {
    //         if (cell.isNode()) {
    //             cell.attr('body', {fill: '#ffd591'})
    //         } else {
    //             cell.attr('line/stroke', '#ffa940')
    //         }
    //     })
    //     removed.forEach((cell) => {
    //         if (cell.isNode()) {
    //             cell.attr('body', {fill: '#fff'})
    //         } else {
    //             cell.attr('line/stroke', '#808080')
    //         }
    //     })
    // })

}

function initChangePort() {
    // 移入显示连接桩
    const changePortsVisible = (visible) => {
        const ports = container.querySelectorAll(
            '.x6-port-body',
        )
        for (let i = 0, len = ports.length; i < len; i = i + 1) {
            ports[i].style.visibility = visible ? 'visible' : 'hidden'
        }
    }

    // 节点和边的移入删除按钮
    graph.on('node:mouseenter', ({node}) => {
        node.addTools({name: 'button-remove'})
        changePortsVisible(true)
    })
    graph.on('node:mouseleave', ({node}) => {
        changePortsVisible(false)
        node.removeTools()
    })
    graph.on('edge:mouseenter', ({edge}) => {
        edge.addTools([
            {name: 'button-remove'},
            {name: 'source-arrowhead'},
            {name: 'target-arrowhead'},
        ])
    })
    graph.on('edge:mouseleave', ({edge}) => {
        edge.removeTools()
    })
}

function toSvg() {
    graph.toSVG((dataUri) => {
        DataUri.downloadDataUri(DataUri.svgToDataUrl(dataUri), 'chart.svg')
    }, ConfigGraph.dowOptions)
}

function toPng() {
    graph.toPNG((dataUri) => {
        DataUri.downloadDataUri(dataUri, 'chart.png')
    }, config.dowOptions)
}

function toJpeg() {
    graph.toJpeg((dataUri) => {
        DataUri.downloadDataUri(dataUri, 'chart.jpeg')
    }, config.dowOptions)
}

function initData(data = { nodes: [], edges: [] }) {
    if (!data) return
    graph.fromJSON(data)
}

function toJson() {
    return graph.toJSON()
}

const UtilGraph = {
    graph,
    init,
    toSvg,
    toPng,
    toJpeg,
    zoom: factor => graph.zoom(factor),
    translate: (tx, ty) => graph.translate(tx, ty),
    addNode: (node) => graph.addNode(node),
    addEdge: (edge) => graph.addEdge(edge),
    initOnNodeConfigEventListen,
    initData,
    toJson
}

export default UtilGraph